using UnityEngine;
using System.Collections;

public class PlayerScript : MonoBehaviour {
	public NetworkPlayer owner;
	public float hInput = 0.0f;
	public float vInput = 0.0f;
	public float fireOne = 0.0f;
	public float fireTwo = 0.0f;
	public float fireThree = 0.0f;
	public float j = 0.0f;
	public float lastH = 0.0f;
	public float lastV = 0.0f;
	public float lastFireOne = 0.0f;
	public float lastFireTwo = 0.0f;
	public float lastFireThree = 0.0f;
	public float lastJump = 0.0f;
	public float hI = 0.0f;
	public float vI = 0.0f;
	public float lF1 = 0.0f;
	public float lF2 = 0.0f;
	public float lF3 = 0.0f;
	public float jump = 0.0f;
	public float isJumping = 0.0f;
	public float jumpTime = 0.0f;
	public float fireDelayOne = 0.5f;
	public float fireDelayTwo = 0.2f;
	public float fireDelayThree = 1.0f;
	public float lastFiredOne = 0.0f;
	public float lastFiredTwo = 0.0f;
	public float speed = 2f;
	public float jumpSpeed = 5.0f;
	public float lastY = 0.0f;
	public bool isWater = false;
	public float waterTimer = 0.0f;
	public Transform swordAttack;
	public Transform spinAttack;
	public Transform fireballAttack;
	public Transform pickup;
	public int weaponType = 0;
	public bool isKnockback = false;
	public Vector3 knockbackDirection;
	public float knockbackTimer = 1.0f;
	public float knockbackMax = 1.0f;
	public CharacterController control;
	// Use this for initialization
	void Start () {
		control = GetComponent<CharacterController>();
	}
	// Update is called once per frame
	void Update () {	
		if(lastFiredOne > 0.0f)
			lastFiredOne -= Time.deltaTime;
		if(lastFiredTwo > 0.0f)
			lastFiredTwo -= Time.deltaTime;
		if(owner != null && Network.player == owner){
			hI= Input.GetAxis("Horizontal");
			vI = Input.GetAxis("Vertical");
			lF1 = Input.GetAxis("Fire1");
			lF2 = Input.GetAxis("Fire2");
			lF3 = Input.GetAxis("Fire3");
			jump = Input.GetAxis("Jump");
			if(lastH != hI || lastV != vI || lastFireOne != lF1 || lastFireTwo != lF2 || lastFireThree != lF3 || lastJump != jump){
				lastH = hI;
				lastV = vI;
				lastFireOne = lF1;
				lastFireTwo = lF2;
				lastFireThree = lF3;
				lastJump = jump;
				if(isKnockback == true){
					lastH = 0;
					lastV = 0;
					lastFireOne = 0;
					lastFireTwo = 0;
					lastFireThree = 0;
					lastJump = 0;
				}
				if(Network.isServer){
					SendMovementInput(hI, vI, lF1, lF2, lF3, lastJump);
				}
				else if(Network.isClient){
					SendMovementInput(hI, vI, lF1, lF2, lF3, lastJump);
					networkView.RPC("SendMovementInput", RPCMode.Server, hI, vI, lF1, lF2, lF3, lastJump);
				}
			}
		}
		if(Network.isServer || Network.player == owner){
			if(isWater){
				if(waterTimer <= 0.0f){
					isWater=false;
					transform.collider.isTrigger = false;
				}
			}
			Vector3 move;
			if(isKnockback == false)
				move = new Vector3(hInput*speed*-1, 0, vInput*speed*-1);
			else
				move = new Vector3(knockbackDirection.x*speed, knockbackDirection.y*speed, knockbackDirection.z*speed);
			if(isKnockback == true){
				knockbackTimer -= Time.deltaTime;
				if(knockbackTimer <= 0){
					isKnockback = false;
				}
			}
			if(isJumping == 1){
				move.y = lastY;
			}
			if(lastJump == 1 && isJumping == 0){
				move.y = jumpSpeed;
				isJumping = 1;
			}
			move.y -= 10 * Time.deltaTime;
			if(lastFiredTwo >= 0.5f){
				if(move.y <= 0.0f){
					move.y = 0;
				}
			}
			lastY = move.y;
			GetComponent<CharacterController>().Move((move)*50*Time.deltaTime);
			if(GetComponent<CharacterController>().collisionFlags == CollisionFlags.Below){
				isJumping = 0;
			}	
			transform.LookAt(new Vector3(transform.position.x+move.x,transform.position.y,transform.position.z+move.z));
			networkView.RPC("PlayerPositionUpdate",RPCMode.Server, transform.position, transform.rotation);
			if(lF1 == 1 && lastFiredOne <= 0.0f){
				Transform sword = (Transform)Network.Instantiate(swordAttack, transform.position + transform.forward*20, transform.rotation, int.Parse(owner+""));
				lastFiredOne = fireDelayOne;
			}
			if(lF2 == 1 && lastFiredTwo <= 0.0f){
				if(weaponType == 0){
					Transform spin = (Transform)Network.Instantiate(spinAttack, transform.position, transform.rotation, int.Parse(owner+""));
					spin.GetComponent<SpinScript>().setTarget(transform,owner);
					lastFiredTwo = fireDelayThree;
				}
				if(weaponType == 1){
					Transform f = (Transform)Network.Instantiate(fireballAttack, transform.position + transform.forward*20 + new Vector3(0,5,0), transform.rotation, int.Parse(owner+""));
					f.GetComponent<fireballScript>().setDir(transform.forward);
					lastFiredTwo = fireDelayTwo;
				}
				if(weaponType == 2){
					isWater = true;
					transform.collider.isTrigger = true;
					waterTimer = fireDelayThree;
				}
			}
			if(lF3 == 1){
				Transform pUp = (Transform)Network.Instantiate(pickup, transform.position, transform.rotation, int.Parse(owner+""));
				pUp.GetComponent<pickupScript>().setParent(transform);
			}
		}
	}
	public void weaponT(int t){
		weaponType = t;
	}
	public void setKnockback(Vector3 dir){
		knockbackDirection = dir;
		isKnockback = true;
		knockbackTimer = knockbackMax;
	}
	[RPC]
	void SetPlayer(NetworkPlayer player){
		owner = player;
	}
	[RPC] 
	void PlayerPositionUpdate(Vector3 pos, Quaternion rot){
		transform.position = pos;
		transform.rotation = rot;
	}
	[RPC]
	void SendMovementInput(float h, float v, float f1, float f2, float f3, float j1){
		hInput = h;
		vInput = v;
		fireOne = f1;
		fireTwo = f2;
		fireThree = f3;
		j = j1;
	}
	void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info){
		if(stream.isWriting){
			Vector3 pos = transform.position;
			stream.Serialize(ref pos);
		}
		else{
			Vector3 posReceive = Vector3.zero;
			stream.Serialize(ref posReceive);
			transform.position = Vector3.Lerp(transform.position, posReceive, 0.9f);
		}
	}
			
}
